package cn.hiapi.shop.api;

import cn.hiapi.basic.ResponseEntity;
import cn.hiapi.basic.controller.BasicController;
import cn.hiapi.basic.enums.ResponseCode;
import cn.hiapi.basic.pay.consts.PayConst;
import cn.hiapi.basic.redis.data.LockConst;
import cn.hiapi.basic.security.TokenGet;
import cn.hiapi.basic.token.Token;
import cn.hiapi.basic.token.enums.TokenType;
import cn.hiapi.finance.dto.WithdrawApply;
import cn.hiapi.finance.entity.Amount;
import cn.hiapi.finance.entity.FinanceBank;
import cn.hiapi.finance.query.AmountGet;
import cn.hiapi.finance.service.AmountService;
import cn.hiapi.finance.service.FinanceBankService;
import cn.hiapi.finance.service.RechargeService;
import cn.hiapi.finance.service.WithdrawService;
import cn.hiapi.interfaces.DispatchContext;
import cn.hiapi.interfaces.ILockService;
import cn.hiapi.interfaces.config.IConfigService;
import cn.hiapi.interfaces.finance.IPaymentService;
import cn.hiapi.interfaces.finance.model.PayTypes;
import cn.hiapi.interfaces.finance.model.RechargeModel;
import cn.hiapi.interfaces.user.IUserVerifyPayPwdService;
import cn.hiapi.shop.request.ShopRechargeRequest;
import cn.hiapi.shop.request.ShopWithdrawApply;
import cn.hiapi.shop.service.shop.ShopLinkUserService;
import cn.hiapi.shopkeeper.consts.AppConst;
import cn.hiapi.utils.JsonUtils;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Map;

/**
 * @author AdinZ
 * @date 2022/12/13 22:45
 */
@RestController("shopkeeperShopAmountController")
@RequestMapping("/shop/amount")
public class AmountController extends BasicController {

    private final DispatchContext dispatchContext;

    public AmountController(DispatchContext dispatchContext) {
        this.dispatchContext = dispatchContext;
    }

    @ApiOperation(value = "余额信息", notes = "余额信息", nickname = "AdinZ")
    @GetMapping("/balance")
    public ResponseEntity balance(@RequestParam("shopId") long shopId,
                                  @RequestParam("type") String type) {
        this.dispatchContext.getServiceOne(ShopLinkUserService.class).verifyShop(TokenGet.get().getFid(), shopId, AppConst.SHOP_ROLE_AMOUNT);
        Amount amount = this.dispatchContext.getServiceOne(AmountService.class).amountGet(new AmountGet(0, shopId, type));
        JsonUtils.Builder builder = JsonUtils.builder();

        builder.put("balance", amount.getAmount());

        if (StringUtils.equals(AppConst.FINANCE_AMOUNT_MONEY, type)) {
            builder.put("wait", 0);
        }
        return toSuccess(builder.build());

    }


    @ApiOperation(value = "提现", notes = "提现", nickname = "AdinZ")
    @PostMapping("/withdraw")
    public ResponseEntity withdraw(@RequestBody ShopWithdrawApply request) {
        Token<Object> token = TokenGet.get();
        String lock = LockConst.getLock("withdraw-shop", token.getFid());
        try {
            this.dispatchContext.getServiceOne(ILockService.class).lockThr(lock);
            this.dispatchContext.getServiceOne(ShopLinkUserService.class).verifyShop(token.getFid(), request.getShopId(), AppConst.SHOP_ROLE_AMOUNT);
            request.setAmountType(AppConst.FINANCE_AMOUNT_MONEY);
            request.setAccountType(AppConst.FID_TYPE_SHOP);

            boolean verifyPwd = this.dispatchContext.getServiceOne(IUserVerifyPayPwdService.class).verifyPwd(token.getFid(), request.getPayPwd());
            if (!verifyPwd) return toError(ResponseCode.PAY_PWD_ERR);

            long id = request.getBank().getLongValue("id");
            FinanceBank bank = this.dispatchContext.getServiceOne(FinanceBankService.class).get(id);
            if (bank == null || bank.getFid() != request.getShopId()) return toError("银行卡id错误");

            request.setBank(
                    JsonUtils.builder()
                            .put("cardNo", bank.getIdCard())
                            .put("name", bank.getBankName())
                            .put("code", bank.getBankCode())
                            .put("realName", bank.getName())
                            .build()
            );
            ResponseEntity response = this.dispatchContext.getServiceOne(WithdrawService.class).apply(0, request.getShopId(), AppConst.FID_TYPE_SHOP, request, null, false);
            return response;
        } finally {
            this.dispatchContext.getServiceOne(ILockService.class).unlock(lock);
        }
    }


    @ApiOperation(value = "充值", notes = "充值", nickname = "AdinZ")
    @PostMapping("/recharge")
    public ResponseEntity recharge(@RequestBody ShopRechargeRequest request) {
        Token<Object> token = TokenGet.get();
        this.dispatchContext.getServiceOne(ShopLinkUserService.class).verifyShop(token.getFid(), request.getShopId(), AppConst.SHOP_ROLE_AMOUNT);
        BigDecimal rate = BigDecimal.ONE;
        if (StringUtils.equalsIgnoreCase(request.getAmountType(), AppConst.FINANCE_AMOUNT_SUGAR)) {
            JSONObject config = this.dispatchContext.getServiceOne(IConfigService.class).getConfig(AppConst.CONFIG_SHOPKEEPER_CONFIG);
            BigDecimal sugarRate = JsonUtils.getBigDecimal(config, "sugar_rate");
            if (sugarRate.compareTo(BigDecimal.ZERO) > 0)
                rate = sugarRate;
        }
        Map map = this.dispatchContext.getServiceOne(IPaymentService.class).createPayment(RechargeModel.builder()
                .fid(request.getShopId())
                .fidType(AppConst.FID_TYPE_SHOP)
                .uid(token.getFid())
                .type("AMOUNT")
                .amountType(request.getAmountType())
                .money(request.getAmount())
                .actual(request.getAmount().multiply(rate))
                .title("商户账户充值")
                .payType("shopkeeper_shop_wx_pay:" + PayConst.WXPAY_PROGRAM)
                .build(), PayTypes.WXPAY_MINI);
        return toSuccess(map);
    }


}
